// +----------------------------------------------------------------------
// | MapABC JavaScript API
// +----------------------------------------------------------------------
// | Copyright (c) 2010 http://MapABC.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed AutoNavi MapABC
// +----------------------------------------------------------------------
// | Author: yhostc <yhostc@gmail.com>
// +----------------------------------------------------------------------
(function(){
	/**
	 +------------------------------------------------------------------------------
	 * 折线编辑功能插件
	 +------------------------------------------------------------------------------
	 */
	MMap.PolyEditor = MMap.Class({
		_type:"polyeditor",
		_map:false,//地图对象
		
		
		guid:MMap.Util.guid(),// 定制唯一主键
		
		initialize:function(map,line){
			this._map = map;//地图对象
			this._line = line;//线对象
			this._list = [];
			this._event = {};
			//IE6,加载PNG透明处理类
			if(!!window.ActiveXObject && !window.XMLHttpRequest && typeof(DD_belatedPNG)=="undefined"){
				new MMap.AjaxRequest(MMap.Conf._plugin+"?cls=iepngfix",function(){},true);
			}
		},
		/**
		 +----------------------------------------------------------
		 * 拖拽结束后添加固定点
		 +----------------------------------------------------------
		 * @param lnglat 经纬度
		 * @param gid 点ID
		 +----------------------------------------------------------
		 */
		_addNode:function(lnglat,gid){
			var obj = this._map,self = this,line=this._line;
			var c = document.createElement("div");
			c.title = "拖动以更改图形";
			c.className = "edit_mapabc";
			c.style.cssText = "width:11px;height:11px;background:url("+MMap.Conf._client+"Images/dd-via.png) 0px 0px no-repeat;";
			var d = document.createElement("img");
			d.tilte = "删除此节点";
			d.style.cssText = "display:none;position:absolute;left:11px;top:-1px;z-Index:101";
			d.src = obj._client+"Images/close.gif";
			d.onclick = function(){
				self._removeNode(gid);
			}
			c.appendChild(d);
			
			// 将当前位置点插入查询数组中
			var mkr = new MMap.Marker({
				id:gid,
				offset:new MMap.Pixel(-5,-5),
				position:lnglat,
				draggable:true, // 可拖拽
				zIndex:100,
				content:c
			});
			obj.addOverlays(mkr);
			
			//显示删除标志
			var mo = function(e){
				//如果小于图形要求节点数，则不能被删除
				if((line._type=="polyline" && self._list.length>2) || (line._type=="polygon" && self._list.length>3)){
					d.style.display = "block";
				}
			};
			obj.bind(mkr,"mouseover",mo);
			//隐藏删除标志
			var mu = function(e){
				d.style.display = "none";
			};
			obj.bind(mkr,"mouseout",mu);
			var dg = function(e){
				var arr=[],lnglat=e.lnglat;
				for(var i=0;i<self._list.length;i++){
					if(self._list[i].id==gid){
						lnglat.id = gid;
						self._list[i] = lnglat;
					}
					arr.push(self._list[i]);
				}
				line.setPath(arr);//重新绘制线路
				obj.trigger(self,"adjust",self);
				//重新计算中心点
				if(line._type=="polygon"){
					self._mMove.setPosition(self._getCenter());
				}
				obj.stopPropagation(e);
			};
			obj.bind(mkr,"dragging",dg);
			
			self._event[gid] = [];
			self._event[gid].push({obj:mkr,t:"dragging",fn:dg});
			self._event[gid].push({obj:mkr,t:"mouseover",fn:mo});
			self._event[gid].push({obj:mkr,t:"mouseout",fn:mu});
			//alert(DD_belatedPNG);
			if(typeof DD_belatedPNG!="undefined"){DD_belatedPNG["fix"](".edit_mapabc");}
			//触发增加节点操作
			obj.trigger(this,"addnode",this);
		},
		/**
		 +----------------------------------------------------------
		 * 打开折线编辑
		 +----------------------------------------------------------
		 */
		open:function(){
			var self = this,obj = this._map,line = this._line;
			//防止重复加载open方法
			self.close();
			//重置对象数组
			this._map.isDragging = true;
			this._list = [],this._event = {};
			var path   = line.getPath();
			for(var i=0;i<path.length;i++){
				var id = "s"+MMap.Util.guid();
				path[i].id = id;
				this._list.push(path[i]);
				
				this._event[id] = [];//定义当前节点事件数组
				this._addNode(path[i],id);
			}
			
			//添加一个点标记，为手柄
			this._point =  new MMap.Marker({
				id:"m"+this.guid,
				offset:new MMap.Pixel(-5,-5),
				position:this._list[0], 
				draggable:true, // 可拖拽
				visible:false, // 初始化隐藏点
				content:"<div title=\"拖动以增加节点\" class=\"edit_mapabc\" style=\"width:11px;height:11px;background:url("+obj._client+"Images/dd-via.png) 0px 0px no-repeat;\"></div>"
			});
			obj.addOverlays(this._point);
			
			var s = 0, // 点标记是否在线轨迹上移动状态
				d = 0; // 点标记是否在拖拽状态
			//调整手柄位置
			var fn = function(e){
				//如果不在移动状态,则不做处理
				if(!s){return false;}
				// 计算鼠标位置与线的点及最短距离
				var c =  [].concat(line.getPath());
				if(line._type=="polygon"){
					c.push(c[0]);
				}
				var poi = self._pt2LineDist(c,e.lnglat);
				if(poi.dis<10){// 如果距离小于10像素,则移动点标记
					if(!self._point){
						obj.unbind(obj,"mousemove",fn);
						return false;
					}
					self._point.setPosition(poi);// 调整点标记位置
				}else{// 超出距离,判断是否在拖拽
					s = 0;//重置移动状态
					if(!d){// 没有拖拽
						//隐藏点标记
						self._point.setVisible(false);
						//注销鼠标移动事件
						obj.unbind(obj,"mousemove",fn);
					}
				}
			};
			//显示手柄
			var mv = function(e){
				s = 1;// 定义移动状态
				self._point.show();//显示手柄
				obj.bind(obj,"mousemove",fn);//注册地图移动事件
			};
			obj.bind(line,"mousemove",mv);
			self._event["p"+self.guid] = [];
			self._event["p"+self.guid].push({obj:line,t:"mousemove",fn:mv});
			
			
			var startPoi,lastList,f=0,gid;
			
			
			//拖拽手柄调整折线形状
			var ds = function(e){//点标记拖拽开始
				d = 1; // 定义拖拽状态
				var arr = [];
				for(var i=0;i<self._list.length;i++){
					arr.push(self._list[i]);
				}
				if(line._type=="polygon"){
					arr.push(arr[0]);
				}
				startPoi = self._pt2LineDist(arr,e.lnglat);
				gid = "s"+MMap.Util.guid();//本次拖拽ID
			};
			
			obj.bind(self._point,"dragstart",ds);
			self._event["m"+self.guid] = [{obj:self._point,t:"dragstart",fn:ds}];//登记手柄事件
			
			//点标记拖拽过程中
			var dg = function(e){
				d = 1;//定义拖拽状态
				//在此位置添加一个固定点
				var lnglat = e.lnglat,list=[],arr=[];
				for(var i=0;i<self._list.length;i++){
					list.push(self._list[i]);
					arr.push(self._list[i]);
					if(i==startPoi.i){
						lnglat.id = gid;
						list.push(lnglat);
						arr.push(lnglat);
					}
				}
				line.setPath(arr);
				lastList = list;//记录最后一次更改的POI
				//触发拖拽调整图形大小事件
				obj.trigger(self,"adjust",self);
			};
			obj.bind(self._point,"dragging",dg);
			self._event["m"+self.guid].push({obj:self._point,t:"dragging",fn:dg});
			
			// 点标记拖拽结束, 添加一个固定的拖拽点
			var de = function(e){
				d = 0;// 重置拖拽状态
				
				self._list = lastList;
				self._event[gid] = [];//定义当前节点事件数组
				self._addNode(e.lnglat,gid);
				//重新计算中心点
				if(line._type=="polygon"){
					self._mMove.setPosition(self._getCenter());
				}
				
				// 隐藏移动点标记
				self._point.hide();
				
				// 销毁地图移动事件，减轻压力
				obj.unbind(obj,"mousemove",fn);
				obj.stopPropagation(e);
			};
			obj.bind(self._point,"dragend",de);
			self._event["m"+self.guid].push({obj:self._point,t:"dragend",fn:de});
	
			if(line._type=="polygon"){//添加移动整体手柄
				 this._mMove =  new MMap.Marker({
					id:"d"+this.guid,
					offset:new MMap.Pixel(-5,-5),
					position:this._getCenter(), 
					draggable:true, // 可拖拽
					zIndex:1000,
					content:"<div title=\"拖动移动图形\" class=\"edit_mapabc\" style=\"width:11px;height:11px;cursor:move;background:url("+obj._client+"Images/dd-via.png) 0px 0px no-repeat;overflow:hidden;\"></div>"
				});
				obj.addOverlays(this._mMove);
				var mX=0,mY=0;
				var mds = function(e){
					mX = e.clientX,mY = e.clientY;
				};
				obj.bind(this._mMove,"dragstart",mds);
				
				var isDragging = 0;
				var mdg = function(e){
					if(isDragging==1){return false;}
					isDragging = 1;
					var x = e.clientX - mX,y = e.clientY - mY;
					var list=[];
					for(var i=0;i<self._list.length;i++){
						var p = obj.lnglatToPixel(self._list[i],obj.level);
						p.x += x,p.y += y;
						var l = obj.pixelToLngLat(p,obj.level);
						l.id = self._list[i].id;
						self._event[l.id][0].obj.setPosition(l);
						list.push(l);
					}
					self._list = list;
					line.setPath([].concat(list));
					//触发拖拽调整位置大小事件
					obj.trigger(self, "move", self);
					mX = e.clientX, mY = e.clientY;
					isDragging = 0;
				};
				obj.bind(this._mMove,"dragging",mdg);
				self._event["d"+self.guid] = [
					{obj:this._mMove,t:"dragstart",fn:mds},
					{obj:this._mMove,t:"draging",fn:mdg}
				];//登记手柄事件
			}
			if(typeof DD_belatedPNG!="undefined"){DD_belatedPNG["fix"](".edit_mapabc");}
			
			//级别改变，自动关闭编辑状态
			var zc = function(){
				self.close();
			};
			obj.bind(obj,"zoomchange",zc);
			self._event["m"+self.guid].push({obj:obj,t:"zoomchange",fn:zc});
		},
		/**
		 +----------------------------------------------------------
		 * 关闭折线编辑
		 +----------------------------------------------------------
		 */
		close:function(){
			var obj = this._map;
			this._map.isDragging = false;
			//销毁所有事件
			for(var i in this._event){
				var a = this._event[i];
				for(var j=0;j<a.length;j++){
					obj.unbind(a[j].obj,a[j].t,a[j].fn);
				}
				this._event[i] = null;
				delete this._event[i];
				obj.removeOverlays(i);
			}
			//清空所有途径点
			this._list = [];
			//清空隐藏的POI
			this._point = null;
			delete this._point;
			//清空手柄
			this._mMove = null;
			delete this._mMove;
			
		},
		/**
		 +----------------------------------------------------------
		 * 删除其中一个途径点
		 +----------------------------------------------------------
		 * @param id 途经点ID
		 +----------------------------------------------------------
		 */
		_removeNode:function(id){
			var arr=[],obj=this._map,self=this;
			for(var i=0;i<this._list.length;i++){
				if(this._list[i].id == id){//删除途径点
					//删除事件
					var a = self._event[id];
					for(var j=0;j<a.length;j++){
						obj.unbind(a[j].obj,a[j].t,a[j].fn);
					}
					this._event[id] = null;
					delete this._event[id];
					obj.removeOverlays(id);
					this._list.splice(i,1);
					i--;
				}else{
					arr.push(this._list[i]);
				}
			}
			this._line.setPath(arr);//重绘
			//重新计算中心点
			if(this._line._type=="polygon"){
				this._mMove.setPosition(this._getCenter());
			}
			//触发删除节点操作
			obj.trigger(this,"removenode",this);
		},
		/**
		 +----------------------------------------------------------
		 * 求点到线集合中最短距离
		 +----------------------------------------------------------
		 * @param line 线经纬度集合
		 * @param Pt 点经纬度坐标
		 +----------------------------------------------------------
		 */
		_pt2LineDist:function(line,Pt) {
			var a={dis:Number.MAX_VALUE};
			for (var i=0;i<line.length-1;i++) {
				var arr = [line[i],line[i+1]];
				var b = this._pt2LineSegmentDist(arr,Pt);
				if (b.dis < a.dis) {
					a = {lng:b.lng,lat:b.lat,dis:b.dis,i:i,_type:"lnglat"};
				}
			}
			//计算像素距离
			a.dis = Math.round(this._map.getDistance(Pt,new MMap.LngLat(a.lng,a.lat))/this._map.getResolution());
			return a;
		},
		/**
		 +----------------------------------------------------------
		 * 求点到线最短距离点及距离
		 +----------------------------------------------------------
		 * @param line 线经纬度集合
		 * @param pt 点经纬度坐标
		 +----------------------------------------------------------
		 */
		_pt2LineSegmentDist:function(line,pt) {
			var x = 0,y = 0;
			var dX = line[1].lng - line[0].lng,dY = line[1].lat - line[0].lat;
			var dR = -(line[0].lat - pt.lat) * dY - (line[0].lng - pt.lng) * dX;
			var dL;
			if (dR <= 0) {
				x = line[0].lng;
				y = line[0].lat;
			} else if (dR >= (dL = dX * dX + dY * dY)) {
				x = line[1].lng;
				y = line[1].lat;
			} else {
				x = line[0].lng + dR * dX / dL;
				y = line[0].lat + dR * dY / dL;
			}
			//返回实地距离
			return {lng:x,lat:y,dis:Math.pow(pt.lng-x,2) + Math.pow(pt.lat - y,2)}
		},
		/**
		 +----------------------------------------------------------
		 * 获取图形中心点位置
		 +----------------------------------------------------------
		 */
		_getCenter:function(line){
			var x = 0,y=0,len=this._list.length;
			for(var i=0;i<len;i++){
				x += this._list[i].lng;
				y += this._list[i].lat;
			}
			return new MMap.LngLat(x/len,y/len);
		}
	});

})(MMap);
